#include "selutility.h"
#include <phosphor-logging/lg2.hpp>
#include <phosphor-logging/elog-errors.hpp>
#include <phosphor-logging/elog.hpp>
#include <xyz/openbmc_project/Common/error.hpp>
#include <xyz/openbmc_project/Logging/SEL/error.hpp>
#include <phosphor-logging/log.hpp>
#include <iomanip>
#include <sstream>
#include <ctime>
#include <iostream>

namespace selutility {

// 将二进制数据转换为十六进制字符串
std::string toHexStr(const std::vector<uint8_t>& data) {
    std::stringstream ss;
    ss << std::hex << std::setfill('0');
    for (const auto& byte : data) {
        ss << std::setw(2) << static_cast<int>(byte);
    }
    return ss.str();
}

// 生成唯一的日志ID
std::string getUniqueEntryID(const std::string& prefix) {
    static time_t prevTs = 0;
    static int index = 0;

    // 获取当前时间戳
    std::time_t curTs = std::time(0);
    std::tm timeStruct = *std::localtime(&curTs);
    char buf[80];
    // 如果时间戳相同，增加索引
    if (curTs == prevTs) {
        index++;
    } else {
        index = 0;
    }
    // 保存时间戳
    prevTs = curTs;
    strftime(buf, sizeof(buf), "%Y-%m-%d.%X", &timeStruct);
    std::string uniqueId = prefix + buf;
    if (index > 0) {
        uniqueId += "_" + std::to_string(index);
    }
    return uniqueId;
}

// 添加IPMI SEL日志
void addIpmiSelLog(const std::string& sensorPath, const std::vector<uint8_t>& eventData) {
    if (sensorPath.empty()) {
        return;
    }

    using namespace phosphor::logging;
    using namespace xyz::openbmc_project::Logging::SEL;
    using SELCreated = sdbusplus::xyz::openbmc_project::Logging::SEL::Error::Created;

    static constexpr auto recordType = 7; // 根据实际需求调整
    static constexpr auto generatorID = 0x20; // 根据实际需求调整

    // 将事件数据转换为十六进制字符串
    std::string selDataStr = toHexStr(eventData);

    // 生成唯一的记录ID
    std::string uniqueEntryID = getUniqueEntryID("SEL_LOG_");

    // 调用 report 函数生成 SEL 日志
    report<SELCreated>(
        Created::RECORD_TYPE(recordType),
        Created::GENERATOR_ID(generatorID),
        Created::SENSOR_DATA(selDataStr.c_str()),
        Created::EVENT_DIR(true),
        Created::SENSOR_PATH(sensorPath.c_str())
    );

}

} // namespace selutility
